﻿using Autodesk.Revit.DB;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoreDB.Extensions
{

    /// <summary>
    /// 包含 CurveLoop，CurveArray
    /// </summary>
    public static class CurveLoopExtension
    {
        private const double defaultEps = 1e-3;
        /// <summary>
        /// 判断CurveLoop是否有效
        /// </summary>
        /// <returns></returns>
        public static bool IsValid(this CurveLoop loop)
        {
            if (loop is null)
                throw new ArgumentNullException(nameof(loop));
            if (!loop.IsValidObject)
                throw new InvalidDataException(nameof(loop));
            if (!loop.Any())
                throw new InvalidDataException(nameof(loop));
            if (!loop.HasPlane())
                return false;
            return true;
        }
        /// <summary>
        /// 是否连续
        /// 空集也是连续的
        /// </summary>
        /// <returns></returns>
        public static bool IsContinuous(this CurveLoop loop)
        {
            if (loop.Any())
                return true;
            bool result = true;
            List<Curve> cs = loop.GetCurves();
            for (int i = 0; i < cs.Count - 1; i++)
                if (!cs[i].End().IsEqual(cs[i + 1].Start(), defaultEps))
                    result = false;
            return result;
        }
        /// <summary>
        /// 是否闭合
        /// 闭合=连续+首尾相连
        /// 空集是开放的
        /// </summary>
        /// <returns></returns>
        public static bool IsClosed(this CurveLoop loop)
        {
            if (loop.IsContinuous() && !loop.Any())
            {
                List<Curve> cs = loop.GetCurves();
                if (cs.First().Start().IsEqual(cs.Last().End(), defaultEps))
                    return true;
            }
            return false;
        }



        /// <summary>
        /// Curveloop矩阵转换
        /// </summary>
        /// <param name="loop"></param>
        /// <param name="transform"></param>
        /// <param name="inverse"></param>
        /// <returns></returns>
        public static CurveLoop OfTrans(this CurveLoop loop, Transform transform, bool inverse = false)
        {
            if (!loop.IsValid())
                throw new InvalidDataException(nameof(loop));
            if (transform is null)
                throw new ArgumentNullException(nameof(transform));
            if (inverse)
                transform = transform.Inverse;
            return CurveLoop.CreateViaTransform(loop, transform);
        }
        public static CurveLoop Clone(this CurveLoop loop)
        {
            return CurveLoop.Create(loop.GetCurves());
        }
        //public static CurveLoop MakeCurveLoop(this IEnumerable<Curve> curves)
        //{
        //    curves.Select(x => x.Clone()).ToList();
        //}
        #region Get
        /// <summary>
        /// 得到闭合回路所有的端点
        /// </summary>
        /// <param name="loop"></param>
        /// <returns></returns>
        public static List<XYZ> GetPoints(this CurveLoop loop)
        {
            var points = new List<XYZ>();
            var curves = loop.GetCurves();
            curves.ForEach(c => points.Add(c.Start()));
            if (loop.IsOpen())
                points.Add(curves.Last().End());
            return points;
        }

        /// <summary>
        /// 得到闭合回路表示的所有曲线
        /// </summary>
        /// <param name="loop"></param>
        /// <returns></returns>
        public static List<Curve> GetCurves(this CurveLoop loop)
        {
            return loop.ToList();
        }
        /// <summary>
        /// 只拿里面的 线段 Line
        /// </summary>
        /// <param name="loop"></param>
        /// <returns></returns>
        public static List<Line> GetLines(this CurveLoop loop)
        {
            List<Line> result = new List<Line>();
            loop.GetCurves().ForEach(x =>
            {
                if (x is Line l)
                    result.Add(l);
            });
            return result;
        }

        public static CurveArray GetCurveArray(this CurveLoop loop)
        {
            var curveArr = new CurveArray();
            loop.GetCurves().ForEach(l => curveArr.Append(l));
            return curveArr;
        }
        #endregion

        /// <summary>
        /// 把CurveLoop拍平，会自动排除垂直线段
        /// </summary>
        /// <param name="loop"></param>
        /// <returns></returns>
        //public static CurveLoop Flat(this CurveLoop loop)
        //{
        //    loop.GetCurves();
        //}

    }
}
